package front
import activity.*
import history.*

class FrontController {
    def emailService
    def counterService
    def regQtyService
    
    def jsCheck() {
    }

    def addCounts() {
        counterService.addCounts(actionName)
    }
   
    def index() {
        addCounts()
        def billboardList = Billboard.findAllByDateStartLessThanEqualsAndDateEndGreaterThanEquals(
            new Date(), new Date())
        if (params.max) params.max = Math.min(max ?: 10, 100)
        //可看到後兩個月活動
//        def td = new GregorianCalendar()
//        td.setTime(new Date())
//        td.add(Calendar.MONTH, 2)
//        def after2M = td.getTime() 
        //println "2m:"+ after2M
        //可報名：DateStart <= today||暑假報：DateStart <= atfer3M，取大atfer3M
        //可報名：DateEnd >= today||暑假報：DateStart >= atfer3M，取小today
//        def serialList = Serial.findAllByRegStartLessThanEqualsAndRegEndGreaterThanEquals(
//            after2M, new Date())
//        def serialList = Serial.findAllByRegStartLessThanEqualsAndRegEndGreaterThanEquals(
//            after2M, new Date())
        //只列出尚未可報名之活動
        def serialList = Serial.findAllByRegEndGreaterThanEquals(new Date())
        [serialInstanceList: serialList, serialInstanceTotal: serialList.size(),
            billboardList: billboardList]
    }
    
    def serialDetail(Long id) {
        addCounts()
        def serial = Serial.get(id)
        if (!serial) {
            flash.message = message(code: 'default.not.found.message', args: [message(code: 'serial.label', default: 'Serial'), id])
            redirect(action: "index")
            return
        }
        def events = serial.events//處理排序問題
        [serial: serial, events: events]
    }
    
    def eventDetail(Long id) {
        addCounts()
        def event = Event.get(id)
        if (!event) {
            flash.message = message(code: 'default.not.found.message', args: [message(code: 'event.label', default: 'Event'), id])
            //redirect(action: "index")
            return
        }
        [event: event]
    }
    
    def dataAgree() {//選好場次，秀同意書
        addCounts()
        //判定單選或多選
        oneMoreParamsIntoSess(session, params)
    }
    
    def dataFill() {//同意書好，填個人資料
        addCounts()
        def events = Event.getAll(session.eventIds*.toLong())
        def serial = events.first().serial
//確保能找出Serial
//println "events:" + events
//println "events.first().serial:" + events.first().serial
//println "serial:" + serial
        def field = unionFields(events)
        session.field = field
        [events: events, serial: serial, field: field, reader: session.reader]
    }
    
    private Field unionFields(def events) {//聯集欄位
        def field = events.last().field//先以最新定義的最後一筆記錄為主
        for (event in events) {
            def newField = event.field
            if (newField?.CID == "R") {
                field.CID = "R"
            } else if (newField?.CID == "Y" && field?.CID == "N") {
                field.CID = "Y"
            }
            if (newField?.service == "R") {
                field.service = "R"
            } else if (newField?.service == "Y" && field?.service == "N") {
                field.service = "Y"
            }
            if (newField?.title == "R") {
                field.title = "R"
            } else if (newField?.title == "Y" && field?.title == "N") {
                field.title = "Y"
            }
            if (newField?.tel1 == "R") {
                field.tel1 = "R"
            } else if (newField?.tel1 == "Y" && field?.tel1 == "N") {
                field.tel1 = "Y"
            }
            if (newField?.tel2 == "R") {
                field.tel2 = "R"
            } else if (newField?.tel2 == "Y" && field?.tel2 == "N") {
                field.tel2 = "Y"
            }
            if (newField?.email1 == "R") {
                field.email1 = "R"
            } else if (newField?.email1 == "Y" && field?.email1 == "N") {
                field.email1 = "Y"
            }
            if (newField?.email2 == "R") {
                field.email2 = "R"
            } else if (newField?.email2 == "Y" && field?.email2 == "N") {
                field.email2 = "Y"
            }
            if (newField?.custom1 == "R") {
                field.custom1 = "R"
                if(event.custom1) {
                    field.custom1Label = event.custom1
                }
            } else if (newField?.custom1 == "Y") {
                field.custom1 = "Y"
                if(event.custom1) {
                    field.custom1Label = event.custom1
                }
            }
            if (newField?.custom2 == "R") {
                field.custom2 = "R"
                if(event.custom2) {
                    field.custom2Label = event.custom2
                }
            } else if (newField?.custom2 == "Y") {
                field.custom2 = "Y"
                if(event.custom2) {
                    field.custom2Label = event.custom2
                }
            }
        }
        if (field == null) {//若未定義都顯示讓讀者可填
            field = new Field(CID:"Y", service:"Y", title:"Y", 
                tel1:"Y", tel2:"N", email1:"Y", email2:"N")
        }
        return field
    }
    
    def dataCheck() {//個人資料好，確認資訊
        addCounts()
        //排除非來自填寫個人資訊頁面
        session.fromDataCheck = true
        //判定單選或多選
        oneMoreParamsIntoSess(session, params)
        def events = Event.getAll(session.eventIds*.toLong())
        //檢查身份證與生日正確
        if (params.CID && params.birth) {
            def cid = params.CID.toUpperCase()
            def query = Reader.where {
                CID == cid
            }
            def users = query.list()
            if (users?.size() > 0) {//現有讀者才需檢查生日
                def day = Date.parse("yyyy/M/d", params.birth)
                //def day = params.birth
                query = Reader.where {
                    CID == cid && birth == day
                }
                users = query.list()
                if (users?.size() < 1) {
                    flash.message = "身份證字號與生日不符！"
                    forward(action: "dataFill")
                }
            }
        }
        //檢查重覆報名
        def dupEvents = []
        def noDupEvents = []
        if (params.CID) {
            session.eventIds = []
            params.CID = params.CID.toUpperCase()
            for(event in events) {
                def c = Register.createCriteria()
                def results = c.listDistinct {
                    eq ('CID', params.CID)
                    eq "event.id", event.id
                    and {
                        ne ('status', '自行取消')
                    }
                }
                if (results?.size() > 0) {
                    dupEvents.add(event)
                } else {
                    //無法自現有Event或session.eventIds移除，會有比對問題remove/minus都出錯，改成加法
                    noDupEvents.add(event)
                    session.eventIds.add(event.id.toString())
                }
            }
        } else {//沒寫CID時，自動判定可報名
            noDupEvents = events
        }

        def serial = events.first().serial
        params.birth = Date.parse("yyyy/M/d", params.birth)
        def reader = new Reader(params)
        if (!reader.validate()) {
            println "ERROR"
            reader.errors.each {
                println it
            }
        }
        session.reader = reader
//println "dupEvents:"+dupEvents.size()
//println "noDupEvents:"+noDupEvents.size()
        [events: noDupEvents, dupEvents: dupEvents, serial: serial, field: session.field, reader: session.reader]
    }
    
    def dataSave() {//存檔並更新資料
        //排除非來自填寫個人資訊頁面
        if (session.fromDataCheck) {
            session.fromDataCheck = null
        } else {
            session.invalidate()
            redirect(action: "index")
            return
        }
        addCounts()
        //reader存檔
        def reader = session.reader
        reader.save()
        //register存檔
        def events = Event.getAll(session.eventIds*.toLong())
        //產生取消碼
        def cancelCode = UUID.randomUUID().toString()
        def register
        for (event in events) {
            register = new Register(
                serial:event.serial, reader:reader, event:event, cancelCode:cancelCode,
                CID:reader.CID, regTime:new Date())
            //判定報名狀態
            def regType
            if (event.isAudit == "Y") {//待審報名
                register.status = "待審報名"
            } else if (event.status == "候補報名") {//候補報名
                register.status = "候補報名"
            } else if (event.status == "尚可報名") {//正取報名
                register.status = "正取報名"
            } else {//例外一律丟待審以免超額
                register.status = "候補報名"
            }
            register.save()
            event.addToRegisters(register)
            register.sysCode = String.format('%08d',register.id)
            register.save()
            //寄信
            emailService.sendMail(register.status, event, reader, register)
            //更新event與serial
            regQtyService.calcRegisterQty(event.id)
        }
        [events: events, serial: events.first().serial, field: session.field, reader: reader, cancelCode: cancelCode]
    }
    
    private def oneMoreParamsIntoSess(def session, def params) {
        //判定單選或多選
        session.eventIds = []
        if (params.reg instanceof String) {
            session.eventIds.add(params.reg)
        } else {
            session.eventIds = params.reg
        }
        //判定單選或多選
        //println "params.reg" + params.reg
        //println "session.eventIds" + session.eventIds
        //println "clazz:" + session.eventIds.class.name
    }
    
    
    def query() {//活動查詢
        addCounts()
    }
    
    def queryResult() {//活動查詢
        addCounts()
        def c = Serial.createCriteria()
        def results = c.listDistinct {
            //def results = c.list {
            def td = new GregorianCalendar()//顯示前一年開始活動
            td.setTime(new Date())
            td.add(Calendar.YEAR, -1)
            def before1Y = td.getTime() 
            ge ('dateStart', before1Y)
            if (params.dateStart) {
                gt ('dateStart', Date.parse("yyyy/M/d", params.dateStart))
            }
            if (params.dateEnd) {
                //                println "----CLASS:"+params.dateStart.getClass()
                //                println "----VALUE:"+params.dateStart
                lt ('dateEnd', Date.parse("yyyy/M/d", params.dateEnd))
            }
            if(params.kind.id){
                events {
                    'in' ('kind.id', new Long(params.kind.id))
                }
            }
            if(params.registerLeft){
                gt ('registerLeft', 0)
            }
            if(params.registerOpen){//變成交集
                def today = new Date()
                and {
                    events {
                        lt ('regStart', today)
                    }
                }
                and{
                    events {
                        gt ('regEnd', today)
                    }
                }
            }
        }
        if (results?.size() == 0) {
            flash.message = '查無結果'
        } else {
            flash.message = ''
        }
        if (params.max) params.max = Math.min(max ?: 10, 100)
        render(view: "query", model: [serialInstanceList: results, serialInstanceTotal: results.size()])
    }
    
    def regQuery() {//報名查詢
        addCounts()
    }

    def regQueryResult() {
        addCounts()
        def c = Register.createCriteria()
        def results = c.listDistinct {
            eq ('CID', params.CID)
            and {
                ne ('status', '自行取消') 
            }
            and {
                reader {
                    eq ('birth', Date.parse("yyyy/M/d", params.birth))
                }
            }
            and {
                event {
                    gt ('dateStart', new Date() - 1)
                }
            }
        }
        //        println "results:"+results.size()
        if (results?.size() == 0) {
            flash.message = '查無結果'
            render(view: "regQuery")
        } else {
            flash.message = ''
            render(view: "regQueryResult", model: [registerList: results, resultsTotal: results.size()])
        }
        //if (params.max) params.max = Math.min(max ?: 10, 100)
    }
   
    def regQueryConfirm() {//取消確認
        addCounts()
        def regList = []
//println "params.cancel:"+params.cancel
        if (params.cancel instanceof String) {
            regList.add(Register.findById(params.cancel))
        } else {
            for (id in params.cancel) {
                regList.add(Register.findById(id))
            }
        }
//println "regList:"+regList
        [registerList: regList, resultsTotal: regList.size()]
    }

    def regQueryCancel() {
        addCounts()
        flash.message = ''
        def cancelList = []
//println "params.cancel:"+params.cancel
        if (params.cancel instanceof String) {
            cancelList.add(params.cancel)
        } else {
            for (id in params.cancel) {
                cancelList.add(id)
            }
        }
//println "cancelList:"+cancelList
        for (id in cancelList) {
            def reg = Register.findById(id)
            if (reg) {
                reg.status = "自行取消"
                flash.message = flash.message + reg.serial.name + "　" + reg.event.name + "　取消報名成功<br/>"
                reg.save()
                regQtyService.calcRegisterQty(reg.event.id)
                //寄信
                emailService.sendMail("自行取消", reg.event, reg.reader, reg)
            }
        }
    }

    def regCancel() {//報名取消
        addCounts()
    }

    def regCancelConfirm() {
        addCounts()
        def regList = Register.findAllByCancelCodeAndStatusNotEqual(params.cancelCode, "自行取消")
        if (regList?.size() == 0) {
            flash.message = '查無結果'
            render(view: "regCancel")
        } else {
            render(view: "regQueryResult", model: [registerList: regList, resultsTotal: regList.size()])
        }
    }


    def serialFull(String id) {
        addCounts()
        def serial = Serial.get(id)
        if (!serial) {
            flash.message = message(code: 'default.not.found.message', args: [message(code: 'serial.label', default: 'Serial'), id])
            redirect(action: "serialFull")
            return
        }
        [serial: serial]
    }
    
    def serialSummeryLink(String id) {
        addCounts()
        def serial = Serial.get(id)
        if (!serial) {
            flash.message = message(code: 'default.not.found.message', args: [message(code: 'serial.label', default: 'Serial'), id])
            redirect(action: "serialStatus")
            return
        }
        [serial: serial]
    }
    
    def checkin(String eventId) {
        addCounts()
        session.eventId = eventId
        def event = []
        event = Event.findById(eventId)
        [event: event]
    }
    
    def checkinResult() {
        def results = []
        //確保為同場，在list加入set參數
        //println "session.eventId:"+session.eventId
        if(!session.eventId) {
            flash.message = '無此場次'
        } else if(params.txt.size() != 4 && params.txt.size() != 10) {
            flash.message = '請輸入正確號碼報到'
        } else if(params.field?.equals("系統碼後四碼")) {
            results = Register.findAllBySysCodeLike("%${params.txt}")
        } else if(params.field?.equals("身分證字號")) {
            results = Register.createCriteria().listDistinct {
                if(session.eventId) {
                    and {
                        event {
                            eq ('id', new Long(session.eventId))
                        }
                    }
                }
                and {
                    reader {
                        eq ('CID', "${params.txt}")
                    }
                }
            }
        } else if (params.field?.equals("身分證後四碼")) {
            results = Register.createCriteria().listDistinct {
                if(session.eventId) {
                    and {
                        event {
                            eq ('id', new Long(session.eventId))
                        }
                    }
                }
                and {
                    reader {
                        like ('CID', "%${params.txt}")
                    }
                }
            }
        } else {
        }
        if (results?.size() > 0) {
            def register = results.first()
            println "reader.name:"+register.reader.name
            println "register.event.id:" + register.event.id
            println "session.eventId:" + session.eventId
            println "if:"+register.event.id.toString().equals(session.eventId)
            if (!register.event.id.toString().equals(session.eventId)) {
                flash.message = "非本場次系統碼"
            } else if (register.present == "未出席") {
                register.present = "已出席"
                register.save()
                flash.message = register.reader.name + "報到完成！"
            } else {
                flash.message = "先前已報到完成！"
            }
        } else if(flash.message) {
        } else {
            flash.message = '查無結果'
        }
        def event = Event.findById(session.eventId)
        session.eventId = session.eventId
        [event: event, resultsList: results]
    }
    
    def clear() {
        session.invalidate()
        redirect(action: "index")
        return
    }
}